;;########################################################################
;; freqmain.lsp
;; Copyright (c) 1999-2002 by Forrest W. Young
;; Continuation of ViSta Plugin for Frequency Analysis.
;; Constructor function, defproto method, load statements and isnew method
;;########################################################################

; PLUGIN STEP 3: CONSTRUCTOR FUNCTION

(defun frequency-analysis 
    (&key
     (table-variables nil)
     (control-variables nil)
     (data   *current-data*)
     (dialog nil))
    "Args: &key table-variables control-variables data dialog
ViSta Frequency Analysis Plugin to calculate chi-square and related statistics for n-way frequency data. The analysis is based on the frequency array for the :TABLE-VARIABLES (a variable name string or a list of variable name strings). By default, the first two (or one) ways of the frequency array become the table variables. Additional ways are treated as the control variables, unless they are explicitly specified as :CONTROL-VARIABLES (a variable name string or a list of variable name strings). The remaining keywords have their usual meaning."
    (send freq-plugin-object-proto :new "Frequency Analysis" 
          data dialog table-variables control-variables))




; PLUGIN STEP 4: DEFPROTO
  
(defproto freq-plugin-object-proto 
  '(table-vars control-vars freq-var nways chisq phi binomial cmh 
    table-labels control-labels observed-data-matrices expected-data-matrices 
	matrix-index-list freqclass-data-matrix) () 
  vista-analysis-plugin-object-proto)




; PLUGIN STEP 5: CODE LOAD STATEMENTS
; The additional files must be in a subdirectory and 
; then loaded here with a statement like this:

(load (strcat *freqs-plugin-path* "freqcode.lsp"))




; PLUGIN STEP 6: ISNEW

(defmeth freq-plugin-object-proto :isnew 
                (title data dialog table-variables control-variables)
  (unless (equal data *current-data*)(setcd data))
  (unless (send data :array) 
          (error-message "Wrong kind of data for frequency analysis."))
  (let* ((vars (send data :active-array-variables))
         (nvars (length vars))
         (ntvars (min nvars 2))
         (1col (and (= 2 (length (array-dimensions (send data :data-array))))
                    (= 1 (second (array-dimensions (send data :data-array))))))
         )
    (flet ((check-vars (check-variables vars type)
            (when (stringp check-variables) 
                  (setf check-variables (list check-variables)))
            (when (not (listp check-variables))
                  (fatal-message "~a variables must be specified as either a variable name string or as a list of one or two variable name strings." type))
            (mapcar #'(lambda (var)
                  (if (not (member var vars))
                      (fatal-message "The variable ~s, specified as a ~a variable, is not found in these data." type))  check-variables))))
      (cond
        (table-variables
         (check-vars table-variables vars "Table")
         (when (length (> table-variables 2)) 
               (fatal-message "Too many table variables. Maximum is 2.")))
        ( t (setf table-variables (select vars (iseq ntvars)))))
      (if control-variables
          (check-vars control-variables vars "Control")
          (when (> ntvars nvars)
                (setf control-variables (select vars (iseq ntvars (1- nvars))))))
      (send self :table-vars table-variables)
      (send self :control-vars control-variables)
      (send self :freq-var (send self :freq-var? data))
      
      (call-next-method title data dialog)
      )))  
